1 Inquinamento a San Andreas

Iniziamo scaricando il dataset dal link dove ho isolato (e pulito) i dati raccolti dall’agenzia americana per la tutela dell’ambiente, relativi alle rilevazioni orarie della concentrazione delle PM10 nell’aria nella città di San Andreas, CA.

Questo dataset è una parte di un dataset molto più grande che si può trovare al link.

Una volta salvato il file nella nostra cartella data passiamo a leggere il suo contenuto.

Possiamo iniziare a prendere confidenza con il dataset leggendo alcune informazioni essenziali, come la dimensione, il nome delle variabili, oppure ne possiamo esplorare la struttura, visualizzare le prime o le ultime righe.

dim(PM10dataSA)
[1] 2581   28

Vediamo subito che il dataset contiene più di 2mila osservazioni per 26 variabili. Accediamo i nomi delle variabili per vedere se riusciamo a capirne il significato.

names(PM10dataSA)
 [1] "X.2"                 "X.1"                 "X"                  
 [4] "State.Code"          "County.Code"         "Site.Num"           
 [7] "Parameter.Code"      "POC"                 "Latitude"           
[10] "Longitude"           "Datum"               "Parameter.Name"     
[13] "Date.Local"          "Time.Local"          "Date.GMT"           
[16] "Time.GMT"            "Sample.Measurement"  "Units.of.Measure"   
[19] "MDL"                 "Uncertainty"         "Qualifier"          
[22] "Method.Type"         "Method.Code"         "Method.Name"        
[25] "State.Name"          "County.Name"         "Date.of.Last.Change"
[28] "DateTime.Local"     

Proseguiamo visualizzando la struttura ed alcune righe dei dati.

str(PM10dataSA)
'data.frame':   2581 obs. of  28 variables:
 $ X.2                : int  1 2 3 4 5 6 7 8 9 10 ...
 $ X.1                : int  1 2 3 4 5 6 7 8 9 10 ...
 $ X                  : int  308088 308089 308090 308091 308092 308093 308094 308095 308096 308097 ...
 $ State.Code         : int  6 6 6 6 6 6 6 6 6 6 ...
 $ County.Code        : int  9 9 9 9 9 9 9 9 9 9 ...
 $ Site.Num           : int  1 1 1 1 1 1 1 1 1 1 ...
 $ Parameter.Code     : int  81102 81102 81102 81102 81102 81102 81102 81102 81102 81102 ...
 $ POC                : int  3 3 3 3 3 3 3 3 3 3 ...
 $ Latitude           : num  38.2 38.2 38.2 38.2 38.2 ...
 $ Longitude          : num  -121 -121 -121 -121 -121 ...
 $ Datum              : Factor w/ 1 level "WGS84": 1 1 1 1 1 1 1 1 1 1 ...
 $ Parameter.Name     : Factor w/ 1 level "PM10 Total 0-10um STP": 1 1 1 1 1 1 1 1 1 1 ...
 $ Date.Local         : Factor w/ 120 levels "2016-01-01","2016-01-02",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Time.Local         : Factor w/ 24 levels "00:00","01:00",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ Date.GMT           : Factor w/ 122 levels "2016-01-01","2016-01-02",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Time.GMT           : Factor w/ 24 levels "00:00","01:00",..: 9 10 11 12 13 14 15 16 17 18 ...
 $ Sample.Measurement : int  25 48 26 14 7 14 11 16 17 11 ...
 $ Units.of.Measure   : Factor w/ 1 level "Micrograms/cubic meter (25 C)": 1 1 1 1 1 1 1 1 1 1 ...
 $ MDL                : int  4 4 4 4 4 4 4 4 4 4 ...
 $ Uncertainty        : logi  NA NA NA NA NA NA ...
 $ Qualifier          : logi  NA NA NA NA NA NA ...
 $ Method.Type        : Factor w/ 1 level "FEM": 1 1 1 1 1 1 1 1 1 1 ...
 $ Method.Code        : int  122 122 122 122 122 122 122 122 122 122 ...
 $ Method.Name        : Factor w/ 1 level "INSTRUMENT MET ONE 4 MODELS - BETA ATTENUATION": 1 1 1 1 1 1 1 1 1 1 ...
 $ State.Name         : Factor w/ 1 level "California": 1 1 1 1 1 1 1 1 1 1 ...
 $ County.Name        : Factor w/ 1 level "Calaveras": 1 1 1 1 1 1 1 1 1 1 ...
 $ Date.of.Last.Change: Factor w/ 4 levels "2016-05-06","2016-05-12",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ DateTime.Local     : Factor w/ 2580 levels "2016-01-01 00:00:00",..: 1 2 3 4 5 6 7 8 9 10 ...
head(PM10dataSA)
tail(PM10dataSA)

Vediamo che i dati contengono indicazioni come coordinate geografiche e lo stato dove sono stati raccolti i dati. Nel caso del dataset originale, queste informazioni sono essenziali per individuare il luogo di raccolta dati, mentre nel nostro caso potrebbero essere omesse, dopo aver verificato che siano consistenti in tutto il dataset.

Siamo interessati a capire l’andamento delle PM10 nel nostro dataset durante il tempo in cui sono stati raccolti i dati. Per prima cosa convertiamo i dati riguardanti le date nel giusto formato, cioè in Date. Usiamo per ora solo le informazioni relative al fuso orario locale.

PM10dataSA$Date.Local <- as.Date(PM10dataSA$Date.Local)

Ora che i dati sono in formatO Date, R capisce che sono numeri salvati con un particolare formato e non stringhe.

In questo modo possiamo, ad esempio, vedere il periodo temporale che coprono usano i comandi min e max.

paste(min(PM10dataSA$Date.Local), which.min(PM10dataSA$Date.Local))
[1] "2016-01-01 1"
paste(max(PM10dataSA$Date.Local), which.max(PM10dataSA$Date.Local))
[1] "2016-04-30 2559"

Possiamo notare che il dataset non supera Aprile e che il max non è assunto nell’ultima osservazione, che sarebbe la 2867. Usando il comando tail() vediamo di capire perché.

tail(PM10dataSA$Date.Local, 25)
 [1] "2016-04-29" "2016-04-29" "2016-04-30" "2016-04-30" "2016-04-30"
 [6] "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30"
[11] "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30"
[16] "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30"
[21] "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30" "2016-04-30"

Fortunatamente vediamo che tutte le ultime 24 rilevazioni sono state fatte durante lo stesso giorno, pertanto il risultato di which.min() non è un errore. Ce lo potevamo aspettare, visto che le misurazioni sono ogni ora, ma è sempre meglio controllare.

Usando la funzione summary() estrapoliamo altre informazioni dal dataset.

summary(PM10dataSA)
      X.2            X.1             X            State.Code  County.Code
 Min.   :   1   Min.   :   1   Min.   :308088   Min.   :6    Min.   :9   
 1st Qu.: 646   1st Qu.: 771   1st Qu.:308858   1st Qu.:6    1st Qu.:9   
 Median :1291   Median :1442   Median :309529   Median :6    Median :9   
 Mean   :1291   Mean   :1464   Mean   :309551   Mean   :6    Mean   :9   
 3rd Qu.:1936   3rd Qu.:2192   3rd Qu.:310279   3rd Qu.:6    3rd Qu.:9   
 Max.   :2581   Max.   :2867   Max.   :310954   Max.   :6    Max.   :9   
                                                                         
    Site.Num Parameter.Code       POC       Latitude      Longitude     
 Min.   :1   Min.   :81102   Min.   :3   Min.   :38.2   Min.   :-120.7  
 1st Qu.:1   1st Qu.:81102   1st Qu.:3   1st Qu.:38.2   1st Qu.:-120.7  
 Median :1   Median :81102   Median :3   Median :38.2   Median :-120.7  
 Mean   :1   Mean   :81102   Mean   :3   Mean   :38.2   Mean   :-120.7  
 3rd Qu.:1   3rd Qu.:81102   3rd Qu.:3   3rd Qu.:38.2   3rd Qu.:-120.7  
 Max.   :1   Max.   :81102   Max.   :3   Max.   :38.2   Max.   :-120.7  
                                                                        
   Datum                    Parameter.Name   Date.Local        
 WGS84:2581   PM10 Total 0-10um STP:2581   Min.   :2016-01-01  
                                           1st Qu.:2016-02-02  
                                           Median :2016-03-01  
                                           Mean   :2016-03-02  
                                           3rd Qu.:2016-04-02  
                                           Max.   :2016-04-30  
                                                               
   Time.Local         Date.GMT       Time.GMT    Sample.Measurement
 19:00  : 116   2016-01-02:  24   03:00  : 116   Min.   : 1.00     
 20:00  : 116   2016-01-03:  24   04:00  : 116   1st Qu.: 4.00     
 06:00  : 113   2016-01-04:  24   02:00  : 113   Median : 7.00     
 07:00  : 113   2016-01-26:  24   05:00  : 113   Mean   : 8.24     
 18:00  : 113   2016-01-28:  24   14:00  : 113   3rd Qu.:11.00     
 21:00  : 113   2016-01-29:  24   15:00  : 113   Max.   :60.00     
 (Other):1897   (Other)   :2437   (Other):1897                     
                      Units.of.Measure      MDL    Uncertainty   
 Micrograms/cubic meter (25 C):2581    Min.   :4   Mode:logical  
                                       1st Qu.:4   NA's:2581     
                                       Median :4                 
                                       Mean   :4                 
                                       3rd Qu.:4                 
                                       Max.   :4                 
                                                                 
 Qualifier      Method.Type  Method.Code 
 Mode:logical   FEM:2581    Min.   :122  
 NA's:2581                  1st Qu.:122  
                            Median :122  
                            Mean   :122  
                            3rd Qu.:122  
                            Max.   :122  
                                         
                                         Method.Name        State.Name  
 INSTRUMENT MET ONE 4 MODELS - BETA ATTENUATION:2581   California:2581  
                                                                        
                                                                        
                                                                        
                                                                        
                                                                        
                                                                        
    County.Name   Date.of.Last.Change             DateTime.Local
 Calaveras:2581   2016-05-06:619      2016-01-01 00:00:00:   1  
                  2016-05-12:656      2016-01-01 01:00:00:   1  
                  2016-06-22:618      2016-01-01 02:00:00:   1  
                  2016-11-08:688      2016-01-01 03:00:00:   1  
                                      2016-01-01 04:00:00:   1  
                                      (Other)            :2575  
                                      NA's               :   1  

Possiamo notare che alcune delle variabili sono trattate come numeriche anche se dovrebbero essere di tipo Factor. Possiamo o convertirle, o semplicemente tenerlo a mente qualora dovessimo lavorarci. Inoltre potremmo eliminare le colonne che non ci interessano usano l’assegnazione <- NULL. Ad esempio, dopo aver verificato che latitudine e longitudine sono le stesse in tutto il dataset, e corrispondono alla città di San Andreas, potremmo eliminarle. Va prima verificato che il dataset non contenga dati estranei, altrimenti eliminando una variabile, potremmo non essere più in grado di capirlo!

Tale verifica si può fare (in questo caso, ma può dipende dai dati) o usando il comando unique(), o anche leggendo i risultati di summary().

Volendo visualizzare i dati, che sono raccolti giornalmente, potrebbe fare comodo una colonna che riporta data e ora, in un formato che R riconosce. Possiamo ottenere tutto ciò con un solo comando. Va segnalato che il datset che è stato fornito, già contiene tale colonna, che è stata creata con il comando:

PM10dataSA$DateTime.Local <- as.POSIXct(paste(PM10dataSA[,c("Date.Local")] , PM10dataSA[,c("Time.Local")] ), format = "%Y-%m-%d %H:%M",  tz="America/Los_Angeles",usetz=TRUE)

Ora possiamo visualizzare i dati usando la funzione plot() aggiungendo delle opportune label lungo gli assi per migliorare la leggibilità.

plot(PM10dataSA$DateTime.Local, PM10dataSA$Sample.Measurement, xlab = "2016", ylab= "PM 10 (ug/m3)", cex = .5)

Poiché il grafico contiene un punto per ogni misurazione oraria, il grafico contiene moltissime informazioni.

Aggiungiamo una linea che indica il limite massimo giornaliero di PM 10 consentito (in Italia).

plot(PM10dataSA$DateTime.Local, PM10dataSA$Sample.Measurement, xlab = "2016", ylab= "PM 10 (ug/m3)", cex = .5)
abline(h = 50, col = "red")

# Per salviare l'immagine
#png(filename="../plot/DailyPM10.png")

Si può notare che (fortunatamente) poche misurazioni superano i limiti consentiti.

2 Dati giornalieri

Vediamo di ridurle il numero di dati, aggregandoli per avere misurazioni giornaliere. Possiamo farlo usando la funzione aggregate() che ci permette di applicare una funzione ad un dataset indicando. Possiamo, ad esempio, decidere di salvare in un nuovo dataset le misure medie e massime per i dati di SA.

DailyVal <- aggregate(PM10dataSA$Sample.Measurement ~ Date.Local, data = PM10dataSA, FUN = mean)
DailyVal[,3] <- aggregate(PM10dataSA$Sample.Measurement ~ Date.Local, data = PM10dataSA, FUN = max)[2]
head(DailyVal)

Possiamo migliorare la leggibilità del dataset cambiando i nomi delle variabili.

names(DailyVal)[2:3] <- c("mean daily PM10", "max daily PM 10")
head(DailyVal)

Visualizziamo ora i dati medi e massimi giornalieri:

plot(DailyVal$Date.Local, DailyVal$`mean daily PM10`, xlab = "2016", ylab= "PM 10 (ug/m3)", cex = .8, main = "Concentrazione media giornaliera di PM10")

plot(DailyVal$Date.Local, DailyVal$`max daily PM 10`, xlab = "2016", ylab= "PM 10 (ug/m3)", cex = .8, main = "Concentrazione massima giornaliera di PM10")
abline(h = 50, col = "red")

Potrebbe essere interessante vedere se il giorno della settimana influenza la concentrazione di PM10, ad esempio in giorni con più traffico potremmo aspettarci più inquinamento.

typeof(DailyVal$Date.Local)
[1] "double"
#Sys.setlocale("LC_TIME","C") #Nomi 
DailyVal$DayOfTheWeek <- weekdays(DailyVal$Date.Local, abbreviate = TRUE)
head(DailyVal)
#ordiniamo i giorni in modo che la settimana inizi di lunedì
# ci sarà utile dopo
DailyVal$DayOfTheWeek <- ordered(DailyVal$DayOfTheWeek, levels=c( "Lun" , "Mar", "Mer" , "Gio", "Ven" ,  "Sab", "Dom" ))

Vediamo di colorare il grafico precedente usando un colore diverso per ogni giorno della settimana.

plot(DailyVal$Date.Local, DailyVal$`max daily PM 10`, xlab = "2016", ylab= "PM 10 (ug/m3)", cex = .8, main = "Concentrazione massima giornaliera di PM10", col = DailyVal$DayOfTheWeek)
abline(h = 50, col = "red")

Vediamo che non sembra che i picchi siano raggiunti negli stessi giorni. Comunque una legenda andrebbe aggiunta. Vediamo con dei boxplot come la quantità media di polveri PM10 è distribuita rispetto ai giorni della settimana.

boxplot(`mean daily PM10` ~ DayOfTheWeek, data = DailyVal, ylab= "PM 10 (ug/m3)")

Aggiungere ad esempio una linea che indica le media delle misurazioni, aiuta a fare un confronto tra i dati.

boxplot( `mean daily PM10` ~ DayOfTheWeek, data = DailyVal, ylab= "PM 10 (ug/m3)")
abline(h = mean(DailyVal$`mean daily PM10`), col = "red")

Vediamo la data in cui è stato assunto il valore massimo:

DailyVal[DailyVal$`mean daily PM10` > 20,]

Che sarà successo quel giorno? Potrebbe essere un errore di lettura?

Se volessimo visualizzare la distribuzione dei dati rispetto ai giorni, possiamo usare la funzione hist(). Purtroppo tale funzione non supporta la notazione ~, perciò dovremo specificare un grafico per giorno della settimana.

Dal grafico possiamo capire come si distribuiscono le misurazioni rispetto ai giorni della settimana. Si usi l’help per comprendere i parametri che sono stati usati.

2.1 Regressione (Esercizio)

Possiamo analizzare la relazione tra tempo e inquinamento usando un modello lineare? Proviamo e cerchiamo di capire se il modello è adeguato.

3 (Extra) Inquinamento in California

Decidiamo ora di concentrare la nostra attenzione sull’inquinamento in California e dopo aver letto il dataset che contiene i valori medi giornalieri di PM10, salviamo un sottoinsieme di dati che contiene solo dati relativi alla California.

PM10data <- read.csv("../data/daily_81102_2016.csv")
dim(PM10data)
[1] 118885     29

Vediamo che il file è molto grande, contiene molte righe e molte variabili. R impiega diverso tempo a leggerlo.

(PM10dataCAL <- PM10data[PM10data$State.Name == "California",])

In questo caso il nome della variabile che ci interessa è Arithmetic.Mean.

Ora vogliamo visualizzare su una mappa quali sono lo città che superano la soglia di inquinamento consentita durante le osservazioni. In R, questa operazione è molto semplice usando i pacchetti maps o RgoogleMaps.

#install.packages("maps")
library(maps)
map("county", "california", xlim=c(-125,-114), ylim=c(32,43))
points( PM10dataCAL[PM10dataCAL$Arithmetic.Mean > 50,c("Longitude", "Latitude")] ,cex = .8, col = "red")

Se vogliamo usare una mappa di Goole Maps possiamo farlo usando il pacchetto dedicato.

library(RgoogleMaps)
map <- RgoogleMaps::GetMap(center="California", zoom = 6)
map1 <- plotmap( lat =  PM10dataCAL[PM10dataCAL$Arithmetic.Mean > 50,c( "Latitude")], lon =  PM10dataCAL[PM10dataCAL$Arithmetic.Mean > 50,c("Longitude")]  ,map = map)

4 (Extra) Inquinamento a Los Angeles

Usiamo lo stesso dataset contenente i dati giornalieri relativi alle PM10 negli Stati Uniti e concentriamoci sulla sola città di Los Angeles.

PM10dataLA <- PM10data[PM10data$City.Name== "Los Angeles",]
dim(PM10dataLA)
[1] 90 29

Vediamo che sono state raccolte 90 osservazioni relative alla sola città di LA, cerchiamo di capire quando e con che frequenza sono state raccolte.

typeof(PM10dataLA)
[1] "list"
PM10dataLA$Date.Local[1:10]
 [1] 2016-01-01 2016-01-07 2016-01-13 2016-01-19 2016-01-25 2016-01-31
 [7] 2016-02-06 2016-02-12 2016-02-18 2016-02-24
336 Levels: 2016-01-01 2016-01-02 2016-01-03 2016-01-04 ... 2016-12-02

Vediamo che le date sono state salvate come liste. In realtà, come già visto, R prevede il formato Date che potrebbe essere utile e più maneggevole di una lista per fare “operazioni aritmetiche”. Convertiamo quindi la colonna in Date.

PM10dataLA$Date.Local <- as.Date(PM10dataLA$Date.Local)
typeof(PM10dataLA$Date.Local)
[1] "double"

La variabile ora risulta di tipo Date. Questo ci permette, ad esempio, di vedere quanti giorni passano tra una rilevazione e l’altra.

diff(PM10dataLA$Date.Local)
Time differences in days
 [1]    6    6    6    6    6    6    6    6    6    6    6    6    6    6
[15]    6    6    6    6    6    6    7    5    6    6    6    6    6    6
[29]    6    6    6    6    6    6    6    6    6    6    6    6    6    6
[43]    6   12 -270    6    6    6    6    6    6    6    6    6    6    6
[57]    6    6   12    6    6    6    6    6    6    6    6    6    6    6
[71]    6    6    6    6    6    6    6    6    6    6    6    6    6    6
[85]    6    6    6    6    6

Salta all’occhio che la frequenza delle registrazioni è circa ogni 6 giorni, ma compare un dato inatteso. Investighiamo meglio cosa è successo.

unique(PM10dataLA$Date.Local)
 [1] "2016-01-01" "2016-01-07" "2016-01-13" "2016-01-19" "2016-01-25"
 [6] "2016-01-31" "2016-02-06" "2016-02-12" "2016-02-18" "2016-02-24"
[11] "2016-03-01" "2016-03-07" "2016-03-13" "2016-03-19" "2016-03-25"
[16] "2016-03-31" "2016-04-06" "2016-04-12" "2016-04-18" "2016-04-24"
[21] "2016-04-30" "2016-05-07" "2016-05-12" "2016-05-18" "2016-05-24"
[26] "2016-05-30" "2016-06-05" "2016-06-11" "2016-06-17" "2016-06-23"
[31] "2016-06-29" "2016-07-05" "2016-07-11" "2016-07-17" "2016-07-23"
[36] "2016-07-29" "2016-08-04" "2016-08-10" "2016-08-16" "2016-08-22"
[41] "2016-08-28" "2016-09-03" "2016-09-09" "2016-09-15" "2016-09-27"
[46] "2016-05-06" "2016-09-21"
length(unique(PM10dataLA$Date.Local))
[1] 47

Capiamo che sebbene le osservazioni siano 90, non tutte si riferiscono a giorni differenti, quindi bisogna capire come gestire le misurazioni ripetute durante lo stesso giorno. Vediamo, ad esempio, cosa caratterizza le misurazioni ripetute del primo giorno dell’anno.

PM10dataLA[PM10dataLA$Date.Local== "2016-01-01",]

Possiamo osservare che ci sono almeno due siti diversi dove vengono raccolti i dati. Questa osservazione segue sia la comparsa di due diversi Site.Num per la stessa data, sia le differenze nei valori di Latitude e Longitude. Vediamo se esistono solo due siti o più.

paste(unique(PM10dataLA$Site.Num) , unique(PM10dataLA$Latitude), unique(PM10dataLA$Longitude))
[1] "1103 34.06659 -118.22688" "5005 33.9508 -118.43043" 

Abbiamo appurato che esistono due (e solo due) siti individuati da diverse coordinate geografiche.

Estrapoliamo ora alcune informazioni per le variabili numeriche usando il comando summary().

summary(PM10dataLA)
   State.Code  County.Code    Site.Num    Parameter.Code       POC     
 Min.   :6    Min.   :37   Min.   :1103   Min.   :81102   Min.   :1.0  
 1st Qu.:6    1st Qu.:37   1st Qu.:1103   1st Qu.:81102   1st Qu.:1.0  
 Median :6    Median :37   Median :3054   Median :81102   Median :1.5  
 Mean   :6    Mean   :37   Mean   :3054   Mean   :81102   Mean   :1.5  
 3rd Qu.:6    3rd Qu.:37   3rd Qu.:5005   3rd Qu.:81102   3rd Qu.:2.0  
 Max.   :6    Max.   :37   Max.   :5005   Max.   :81102   Max.   :2.0  
                                                                       
    Latitude       Longitude        Datum                  Parameter.Name
 Min.   :33.95   Min.   :-118.4   NAD83: 0   PM10 Total 0-10um STP:90    
 1st Qu.:33.95   1st Qu.:-118.4   WGS84:90                               
 Median :34.01   Median :-118.3                                          
 Mean   :34.01   Mean   :-118.3                                          
 3rd Qu.:34.07   3rd Qu.:-118.2                                          
 Max.   :34.07   Max.   :-118.2                                          
                                                                         
      Sample.Duration         Pollutant.Standard   Date.Local        
 24 HOUR      :90     PM10 24-hour 2006:90       Min.   :2016-01-01  
 24-HR BLK AVG: 0                                1st Qu.:2016-03-07  
                                                 Median :2016-05-15  
                                                 Mean   :2016-05-14  
                                                 3rd Qu.:2016-07-21  
                                                 Max.   :2016-09-27  
                                                                     
                      Units.of.Measure    Event.Type Observation.Count
 Micrograms/cubic meter (25 C):90      Excluded: 0   Min.   :1        
                                       Included: 0   1st Qu.:1        
                                       None    :90   Median :1        
                                                     Mean   :1        
                                                     3rd Qu.:1        
                                                     Max.   :1        
                                                                      
 Observation.Percent Arithmetic.Mean X1st.Max.Value  X1st.Max.Hour
 Min.   :100         Min.   : 6.00   Min.   : 6.00   Min.   :0    
 1st Qu.:100         1st Qu.:16.00   1st Qu.:16.00   1st Qu.:0    
 Median :100         Median :20.50   Median :20.50   Median :0    
 Mean   :100         Mean   :22.18   Mean   :22.18   Mean   :0    
 3rd Qu.:100         3rd Qu.:28.00   3rd Qu.:28.00   3rd Qu.:0    
 Max.   :100         Max.   :57.00   Max.   :57.00   Max.   :0    
                                                                  
      AQI         Method.Code
 Min.   : 6.00   Min.   :63  
 1st Qu.:15.00   1st Qu.:63  
 Median :19.00   Median :63  
 Mean   :20.54   Mean   :63  
 3rd Qu.:26.00   3rd Qu.:63  
 Max.   :52.00   Max.   :63  
                             
                                      Method.Name
 HI-VOL SA/GMW-1200 - GRAVIMETRIC           :90  
  -                                         : 0  
 BGI Inc. Model PQ200 PM10 - Gravimetric    : 0  
 Hi Vol SSI Ecotech Model 3000 - Gravimetric: 0  
 HI-VOL-SA/GMW-321-B - GRAVIMETRIC          : 0  
 HI-VOL-WEDDING-INLET - GRAVIMETRIC         : 0  
 (Other)                                    : 0  
                                             Local.Site.Name
 LAX Hastings                                        :45    
 Los Angeles-North Main Street                       :45    
                                                     : 0    
 1 Site (Met Station and Hi-Vols BA1 and BA1-B)      : 0    
 10 METER TOWER, AT NW CORNER, U OF I RESEARCH CENTER: 0    
 19th & Burt                                         : 0    
 (Other)                                             : 0    
                                   Address        State.Name
 1630 N MAIN ST, LOS ANGELES           :45   California:90  
 7201 W. WESTCHESTER PARKWAY           :45   Alabama   : 0  
  151 NO SUNRISE BLVD, ROSEVILLE, CA   : 0   Alaska    : 0  
  201 ASHVILLE ROAD                    : 0   Arizona   : 0  
  2220 NORTH STREET, ANDERSON, CA 96007: 0   Arkansas  : 0  
  3337 Sandy Way, South Lake Tahoe, CA : 0   Colorado  : 0  
 (Other)                               : 0   (Other)   : 0  
      County.Name           City.Name 
 Los Angeles:90   Los Angeles    :90  
 Ada        : 0   Aberdeen       : 0  
 Adair      : 0   Ajo            : 0  
 Adams      : 0   Ak-Chin Village: 0  
 Alamosa    : 0   Alamosa        : 0  
 Albany     : 0   Albuquerque    : 0  
 (Other)    : 0   (Other)        : 0  
                              CBSA.Name  Date.of.Last.Change
 Los Angeles-Long Beach-Anaheim, CA:90   2016-12-20:90      
                                   : 0   2016-04-11: 0      
 Aberdeen, SD                      : 0   2016-04-15: 0      
 Albuquerque, NM                   : 0   2016-05-11: 0      
 Allentown-Bethlehem-Easton, PA-NJ : 0   2016-05-13: 0      
 Altoona, PA                       : 0   2016-05-18: 0      
 (Other)                           : 0   (Other)   : 0      

Possiamo notare che, anche in questo caso, alcune delle variabili sono trattate come numeriche anche se dovrebbero essere di tipo Factor. Possiamo o convertirle, o semplicemente tenerlo a mente qualora dovessimo lavorarci. Possiamo altrimenti rimuoverle come visto prima.

Per prima cosa, definiamo un campo di interesse. Se vogliamo, ad esempio, vedere l’andamento delle misurazioni medie di PM10 nei due siti, molte delle variabili non ci interessano. Possiamo investigare più nel dettaglio le variabili legate alla nostra indagine e non considerare le altre:

boxplot(Arithmetic.Mean ~ Site.Num, data = PM10dataLA)

Possiamo notare che uno dei due siti presenta delle misurazioni che in generale sono più alte.

Vediamo spazialmente dove sono posizionati i due punti di monitoraggio, questo potrebbe spiegare le differenze nelle misurazioni.

Dalla mappa sembra che uno dei due siti (cerchi neri) sia in centro mentre il secondo è più vicino alla spiaggia, dove possiamo aspettarci meno traffico.

Per avere una comprensione migliore visualizziamo una mappa differente, che mostra sia le strade che l’immagine satellitare della zona.

Vediamo che il secondo punto di osservazione, sebbene registri valori più bassi, probabilmente perché più vicino alla spiaggia, è comunque vicino all’aeroporto. Questo sicuramente influenza la qualità dell’aria e potrebbe spiegare perché sebbene più bassi, i valori non siano bassissimi. Non ci stupirebbe se altri parametri misurati fossero addirittura peggiori rispetto a quelli registrati in centro.

Senza opportuni strumenti di visualizzazione dei dati, non saremmo potuti giungere a queste conclusioni.

LS0tCnRpdGxlOiAiQW5hbGl6emFyZSBpIGRhdGFzZXQgcmVsYXRpdmkgYWxsJ2lucXVpbmFtZW50byIKYXV0aG9yOiAiRmVkZXJpY28gUmVhbGkiCmRhdGU6IDI0LzA1LzIwMTcKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IG5vCiAgICAgIHNtb290aF9zY3JvbGw6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCiAgICB0aGVtZTogeWV0aQogICAgaGlnaGxpZ2h0OiB0YW5nbwotLS0KCiMgSW5xdWluYW1lbnRvIGEgU2FuIEFuZHJlYXMKCkluaXppYW1vIHNjYXJpY2FuZG8gaWwgZGF0YXNldCBkYWwgW2xpbmtdKGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvOXp4MmR0bmU5Z25hZmNtL1BNMTBkYXRhU2FuQW5kcmVhcy5jc3Y/ZGw9MCkgZG92ZSBobyBpc29sYXRvIChlIHB1bGl0bykgaSBkYXRpIHJhY2NvbHRpIGRhbGwnYWdlbnppYSBhbWVyaWNhbmEgcGVyIGxhIHR1dGVsYSBkZWxsJ2FtYmllbnRlLCByZWxhdGl2aSBhbGxlIHJpbGV2YXppb25pIG9yYXJpZSBkZWxsYSBjb25jZW50cmF6aW9uZSBkZWxsZSBQTTEwIG5lbGwnYXJpYSBuZWxsYSBjaXR0w6AgZGkgU2FuIEFuZHJlYXMsIENBLgoKUXVlc3RvIGRhdGFzZXQgw6ggdW5hIHBhcnRlIGRpIHVuIGRhdGFzZXQgbW9sdG8gcGnDuSBncmFuZGUgY2hlIHNpIHB1w7IgdHJvdmFyZSBhbCBbbGlua10oaHR0cDovL2Fxc2RyMS5lcGEuZ292L2Fxc3dlYi9hcXN0bXAvYWlyZGF0YS9kb3dubG9hZF9maWxlcy5odG1sI1JhdykuCgpVbmEgdm9sdGEgc2FsdmF0byBpbCBmaWxlIG5lbGxhIG5vc3RyYSBjYXJ0ZWxsYSBfZGF0YV8gcGFzc2lhbW8gYSBsZWdnZXJlIGlsIHN1byBjb250ZW51dG8uCgpgYGB7cn0KKFBNMTBkYXRhU0EgPC0gcmVhZC5jc3YoIi4uL2RhdGEvUE0xMGRhdGFTYW5BbmRyZWFzLmNzdiIpKQpgYGAKClBvc3NpYW1vIGluaXppYXJlIGEgcHJlbmRlcmUgY29uZmlkZW56YSBjb24gaWwgZGF0YXNldCBsZWdnZW5kbyBhbGN1bmUgaW5mb3JtYXppb25pIGVzc2VuemlhbGksIGNvbWUgbGEgZGltZW5zaW9uZSwgaWwgbm9tZSBkZWxsZSB2YXJpYWJpbGksIG9wcHVyZSBuZSBwb3NzaWFtbyBlc3Bsb3JhcmUgbGEgc3RydXR0dXJhLCB2aXN1YWxpenphcmUgbGUgcHJpbWUgbyBsZSB1bHRpbWUgcmlnaGUuCgpgYGB7cn0KZGltKFBNMTBkYXRhU0EpCmBgYAoKVmVkaWFtbyBzdWJpdG8gY2hlIGlsIGRhdGFzZXQgY29udGllbmUgcGnDuSBkaSAybWlsYSBvc3NlcnZhemlvbmkgcGVyIDI2IHZhcmlhYmlsaS4gQWNjZWRpYW1vIGkgbm9taSBkZWxsZSB2YXJpYWJpbGkgcGVyIHZlZGVyZSBzZSByaXVzY2lhbW8gYSBjYXBpcm5lIGlsIHNpZ25pZmljYXRvLgoKYGBge3J9Cm5hbWVzKFBNMTBkYXRhU0EpCmBgYApQcm9zZWd1aWFtbyB2aXN1YWxpenphbmRvIGxhIHN0cnV0dHVyYSBlZCBhbGN1bmUgcmlnaGUgZGVpIGRhdGkuCgpgYGB7cn0Kc3RyKFBNMTBkYXRhU0EpCmhlYWQoUE0xMGRhdGFTQSkKdGFpbChQTTEwZGF0YVNBKQpgYGAKClZlZGlhbW8gY2hlIGkgZGF0aSBjb250ZW5nb25vIGluZGljYXppb25pIGNvbWUgY29vcmRpbmF0ZSBnZW9ncmFmaWNoZSBlIGxvIHN0YXRvIGRvdmUgc29ubyBzdGF0aSByYWNjb2x0aSBpIGRhdGkuIE5lbCBjYXNvIGRlbCBkYXRhc2V0IG9yaWdpbmFsZSwgcXVlc3RlIGluZm9ybWF6aW9uaSBzb25vIGVzc2VuemlhbGkgcGVyIGluZGl2aWR1YXJlIGlsIGx1b2dvIGRpIHJhY2NvbHRhIGRhdGksIG1lbnRyZSBuZWwgbm9zdHJvIGNhc28gcG90cmViYmVybyBlc3NlcmUgb21lc3NlLCAqKmRvcG8qKiBhdmVyIHZlcmlmaWNhdG8gY2hlIHNpYW5vIGNvbnNpc3RlbnRpIGluIHR1dHRvIGlsIGRhdGFzZXQuCgpTaWFtbyBpbnRlcmVzc2F0aSBhIGNhcGlyZSBsJ2FuZGFtZW50byBkZWxsZSBQTTEwIG5lbCBub3N0cm8gZGF0YXNldCBkdXJhbnRlIGlsIHRlbXBvIGluIGN1aSBzb25vIHN0YXRpIHJhY2NvbHRpIGkgZGF0aS4gUGVyIHByaW1hIGNvc2EgY29udmVydGlhbW8gaSBkYXRpIHJpZ3VhcmRhbnRpIGxlIGRhdGUgbmVsIGdpdXN0byBmb3JtYXRvLCBjaW/DqCBpbiAqRGF0ZSouIFVzaWFtbyBwZXIgb3JhIHNvbG8gbGUgaW5mb3JtYXppb25pIHJlbGF0aXZlIGFsIGZ1c28gb3JhcmlvIGxvY2FsZS4KCmBgYHtyfQpQTTEwZGF0YVNBJERhdGUuTG9jYWwgPC0gYXMuRGF0ZShQTTEwZGF0YVNBJERhdGUuTG9jYWwpCmBgYApPcmEgY2hlIGkgZGF0aSBzb25vIGluIGZvcm1hdE8gKkRhdGUqLCBSIGNhcGlzY2UgY2hlIHNvbm8gbnVtZXJpIHNhbHZhdGkgY29uIHVuIHBhcnRpY29sYXJlIGZvcm1hdG8gZSBub24gc3RyaW5naGUuCgpJbiBxdWVzdG8gbW9kbyBwb3NzaWFtbywgYWQgZXNlbXBpbywgdmVkZXJlIGlsIHBlcmlvZG8gdGVtcG9yYWxlIGNoZSBjb3Byb25vIHVzYW5vIGkgY29tYW5kaSBtaW4gZSBtYXguCgpgYGB7cn0KcGFzdGUobWluKFBNMTBkYXRhU0EkRGF0ZS5Mb2NhbCksIHdoaWNoLm1pbihQTTEwZGF0YVNBJERhdGUuTG9jYWwpKQoKcGFzdGUobWF4KFBNMTBkYXRhU0EkRGF0ZS5Mb2NhbCksIHdoaWNoLm1heChQTTEwZGF0YVNBJERhdGUuTG9jYWwpKQpgYGAKUG9zc2lhbW8gbm90YXJlIGNoZSBpbCBkYXRhc2V0IG5vbiBzdXBlcmEgQXByaWxlIGUgY2hlIGlsIG1heCBub24gw6ggYXNzdW50byBuZWxsJ3VsdGltYSBvc3NlcnZhemlvbmUsIGNoZSBzYXJlYmJlIGxhIDI4NjcuIFVzYW5kbyBpbCBjb21hbmRvIGB0YWlsKClgIHZlZGlhbW8gZGkgY2FwaXJlIHBlcmNow6kuCgpgYGB7cn0KdGFpbChQTTEwZGF0YVNBJERhdGUuTG9jYWwsIDI1KQpgYGAKCkZvcnR1bmF0YW1lbnRlIHZlZGlhbW8gY2hlIHR1dHRlIGxlIHVsdGltZSAyNCByaWxldmF6aW9uaSBzb25vIHN0YXRlIGZhdHRlIGR1cmFudGUgbG8gc3Rlc3NvIGdpb3JubywgcGVydGFudG8gaWwgcmlzdWx0YXRvIGRpIGB3aGljaC5taW4oKWAgbm9uIMOoIHVuIGVycm9yZS4gQ2UgbG8gcG90ZXZhbW8gYXNwZXR0YXJlLCB2aXN0byBjaGUgbGUgbWlzdXJhemlvbmkgc29ubyBvZ25pIG9yYSwgbWEgw6ggc2VtcHJlIG1lZ2xpbyBjb250cm9sbGFyZS4KClVzYW5kbyBsYSBmdW56aW9uZSBgc3VtbWFyeSgpYCBlc3RyYXBvbGlhbW8gYWx0cmUgaW5mb3JtYXppb25pIGRhbCBkYXRhc2V0LgoKYGBge3J9CnN1bW1hcnkoUE0xMGRhdGFTQSkKYGBgCgpQb3NzaWFtbyBub3RhcmUgY2hlIGFsY3VuZSBkZWxsZSB2YXJpYWJpbGkgc29ubyB0cmF0dGF0ZSBjb21lIG51bWVyaWNoZSBhbmNoZSBzZSBkb3ZyZWJiZXJvIGVzc2VyZSBkaSB0aXBvIEZhY3Rvci4gUG9zc2lhbW8gbyBjb252ZXJ0aXJsZSwgbyBzZW1wbGljZW1lbnRlIHRlbmVybG8gYSBtZW50ZSBxdWFsb3JhIGRvdmVzc2ltbyBsYXZvcmFyY2kuIElub2x0cmUgcG90cmVtbW8gZWxpbWluYXJlIGxlIGNvbG9ubmUgY2hlIG5vbiBjaSBpbnRlcmVzc2FubyB1c2FubyBsJ2Fzc2VnbmF6aW9uZSBgPC0gTlVMTGAuIEFkIGVzZW1waW8sICoqZG9wbyoqIGF2ZXIgdmVyaWZpY2F0byBjaGUgbGF0aXR1ZGluZSBlIGxvbmdpdHVkaW5lIHNvbm8gbGUgc3Rlc3NlIGluIHR1dHRvIGlsIGRhdGFzZXQsIGUgY29ycmlzcG9uZG9ubyBhbGxhIGNpdHTDoCBkaSBTYW4gQW5kcmVhcywgcG90cmVtbW8gZWxpbWluYXJsZS4gVmEgcHJpbWEgdmVyaWZpY2F0byBjaGUgaWwgZGF0YXNldCBub24gY29udGVuZ2EgZGF0aSBlc3RyYW5laSwgYWx0cmltZW50aSBlbGltaW5hbmRvIHVuYSB2YXJpYWJpbGUsIHBvdHJlbW1vIG5vbiBlc3NlcmUgcGnDuSBpbiBncmFkbyBkaSBjYXBpcmxvIQoKVGFsZSB2ZXJpZmljYSBzaSBwdcOyIGZhcmUgKGluIHF1ZXN0byBjYXNvLCBtYSBwdcOyIGRpcGVuZGUgZGFpIGRhdGkpIG8gdXNhbmRvIGlsIGNvbWFuZG8gYHVuaXF1ZSgpYCwgbyBhbmNoZSBsZWdnZW5kbyBpIHJpc3VsdGF0aSBkaSBgc3VtbWFyeSgpYC4KClZvbGVuZG8gdmlzdWFsaXp6YXJlIGkgZGF0aSwgY2hlIHNvbm8gcmFjY29sdGkgZ2lvcm5hbG1lbnRlLCBwb3RyZWJiZSBmYXJlIGNvbW9kbyB1bmEgY29sb25uYSBjaGUgcmlwb3J0YSBkYXRhIGUgb3JhLCBpbiB1biBmb3JtYXRvIGNoZSBSIHJpY29ub3NjZS4gClBvc3NpYW1vIG90dGVuZXJlIHR1dHRvIGNpw7IgY29uIHVuIHNvbG8gY29tYW5kby4gVmEgc2VnbmFsYXRvIGNoZSBpbCBkYXRzZXQgY2hlIMOoIHN0YXRvIGZvcm5pdG8sIGdpw6AgY29udGllbmUgdGFsZSBjb2xvbm5hLCBjaGUgw6ggc3RhdGEgY3JlYXRhIGNvbiBpbCBjb21hbmRvOgoKYGBge3J9ClBNMTBkYXRhU0EkRGF0ZVRpbWUuTG9jYWwgPC0gYXMuUE9TSVhjdChwYXN0ZShQTTEwZGF0YVNBWyxjKCJEYXRlLkxvY2FsIildICwgUE0xMGRhdGFTQVssYygiVGltZS5Mb2NhbCIpXSApLCBmb3JtYXQgPSAiJVktJW0tJWQgJUg6JU0iLCAgdHo9IkFtZXJpY2EvTG9zX0FuZ2VsZXMiLHVzZXR6PVRSVUUpCgpgYGAKCk9yYSBwb3NzaWFtbyB2aXN1YWxpenphcmUgaSBkYXRpIHVzYW5kbyBsYSBmdW56aW9uZSBgcGxvdCgpYCBhZ2dpdW5nZW5kbyBkZWxsZSBvcHBvcnR1bmUgbGFiZWwgbHVuZ28gZ2xpIGFzc2kgcGVyIG1pZ2xpb3JhcmUgbGEgbGVnZ2liaWxpdMOgLgoKYGBge3J9CnBsb3QoUE0xMGRhdGFTQSREYXRlVGltZS5Mb2NhbCwgUE0xMGRhdGFTQSRTYW1wbGUuTWVhc3VyZW1lbnQsIHhsYWIgPSAiMjAxNiIsIHlsYWI9ICJQTSAxMCAodWcvbTMpIiwgY2V4ID0gLjUpCmBgYAoKUG9pY2jDqSBpbCBncmFmaWNvIGNvbnRpZW5lIHVuIHB1bnRvIHBlciBvZ25pIG1pc3VyYXppb25lIG9yYXJpYSwgaWwgZ3JhZmljbyBjb250aWVuZSBtb2x0aXNzaW1lIGluZm9ybWF6aW9uaS4gCgpBZ2dpdW5naWFtbyB1bmEgbGluZWEgY2hlIGluZGljYSBpbCBsaW1pdGUgbWFzc2ltbyBnaW9ybmFsaWVybyBkaSBQTSAxMCBjb25zZW50aXRvIChpbiBJdGFsaWEpLgoKYGBge3J9CnBsb3QoUE0xMGRhdGFTQSREYXRlVGltZS5Mb2NhbCwgUE0xMGRhdGFTQSRTYW1wbGUuTWVhc3VyZW1lbnQsIHhsYWIgPSAiMjAxNiIsIHlsYWI9ICJQTSAxMCAodWcvbTMpIiwgY2V4ID0gLjUpCmFibGluZShoID0gNTAsIGNvbCA9ICJyZWQiKQojIFBlciBzYWx2aWFyZSBsJ2ltbWFnaW5lCiNwbmcoZmlsZW5hbWU9Ii4uL3Bsb3QvRGFpbHlQTTEwLnBuZyIpCmBgYAoKU2kgcHXDsiBub3RhcmUgY2hlIChmb3J0dW5hdGFtZW50ZSkgcG9jaGUgbWlzdXJhemlvbmkgc3VwZXJhbm8gaSBsaW1pdGkgY29uc2VudGl0aS4KCiMgRGF0aSBnaW9ybmFsaWVyaQoKVmVkaWFtbyBkaSByaWR1cmxlIGlsIG51bWVybyBkaSBkYXRpLCBhZ2dyZWdhbmRvbGkgcGVyIGF2ZXJlIG1pc3VyYXppb25pIGdpb3JuYWxpZXJlLiBQb3NzaWFtbyBmYXJsbyB1c2FuZG8gbGEgZnVuemlvbmUgYGFnZ3JlZ2F0ZSgpYCBjaGUgY2kgcGVybWV0dGUgZGkgYXBwbGljYXJlIHVuYSBmdW56aW9uZSBhZCB1biBkYXRhc2V0IGluZGljYW5kby4gUG9zc2lhbW8sIGFkIGVzZW1waW8sIGRlY2lkZXJlIGRpIHNhbHZhcmUgaW4gdW4gbnVvdm8gZGF0YXNldCBsZSBtaXN1cmUgbWVkaWUgZSBtYXNzaW1lIHBlciBpIGRhdGkgZGkgU0EuCgpgYGB7cn0KRGFpbHlWYWwgPC0gYWdncmVnYXRlKFBNMTBkYXRhU0EkU2FtcGxlLk1lYXN1cmVtZW50IH4gRGF0ZS5Mb2NhbCwgZGF0YSA9IFBNMTBkYXRhU0EsIEZVTiA9IG1lYW4pCkRhaWx5VmFsWywzXSA8LSBhZ2dyZWdhdGUoUE0xMGRhdGFTQSRTYW1wbGUuTWVhc3VyZW1lbnQgfiBEYXRlLkxvY2FsLCBkYXRhID0gUE0xMGRhdGFTQSwgRlVOID0gbWF4KVsyXQpoZWFkKERhaWx5VmFsKQpgYGAKClBvc3NpYW1vIG1pZ2xpb3JhcmUgbGEgbGVnZ2liaWxpdMOgIGRlbCBkYXRhc2V0IGNhbWJpYW5kbyBpIG5vbWkgZGVsbGUgdmFyaWFiaWxpLgoKYGBge3J9Cm5hbWVzKERhaWx5VmFsKVsyOjNdIDwtIGMoIm1lYW4gZGFpbHkgUE0xMCIsICJtYXggZGFpbHkgUE0gMTAiKQpoZWFkKERhaWx5VmFsKQpgYGAKClZpc3VhbGl6emlhbW8gb3JhIGkgZGF0aSBtZWRpIGUgbWFzc2ltaSBnaW9ybmFsaWVyaToKCmBgYHtyfQpwbG90KERhaWx5VmFsJERhdGUuTG9jYWwsIERhaWx5VmFsJGBtZWFuIGRhaWx5IFBNMTBgLCB4bGFiID0gIjIwMTYiLCB5bGFiPSAiUE0gMTAgKHVnL20zKSIsIGNleCA9IC44LCBtYWluID0gIkNvbmNlbnRyYXppb25lIG1lZGlhIGdpb3JuYWxpZXJhIGRpIFBNMTAiKQpgYGAKCmBgYHtyfQpwbG90KERhaWx5VmFsJERhdGUuTG9jYWwsIERhaWx5VmFsJGBtYXggZGFpbHkgUE0gMTBgLCB4bGFiID0gIjIwMTYiLCB5bGFiPSAiUE0gMTAgKHVnL20zKSIsIGNleCA9IC44LCBtYWluID0gIkNvbmNlbnRyYXppb25lIG1hc3NpbWEgZ2lvcm5hbGllcmEgZGkgUE0xMCIpCmFibGluZShoID0gNTAsIGNvbCA9ICJyZWQiKQpgYGAKClBvdHJlYmJlIGVzc2VyZSBpbnRlcmVzc2FudGUgdmVkZXJlIHNlIGlsIGdpb3JubyBkZWxsYSBzZXR0aW1hbmEgaW5mbHVlbnphIGxhIGNvbmNlbnRyYXppb25lIGRpIFBNMTAsIGFkIGVzZW1waW8gaW4gZ2lvcm5pIGNvbiBwacO5IHRyYWZmaWNvIHBvdHJlbW1vIGFzcGV0dGFyY2kgcGnDuSBpbnF1aW5hbWVudG8uCgpgYGB7cn0KdHlwZW9mKERhaWx5VmFsJERhdGUuTG9jYWwpCiNTeXMuc2V0bG9jYWxlKCJMQ19USU1FIiwiQyIpICNOb21pIApEYWlseVZhbCREYXlPZlRoZVdlZWsgPC0gd2Vla2RheXMoRGFpbHlWYWwkRGF0ZS5Mb2NhbCwgYWJicmV2aWF0ZSA9IFRSVUUpCmhlYWQoRGFpbHlWYWwpCiNvcmRpbmlhbW8gaSBnaW9ybmkgaW4gbW9kbyBjaGUgbGEgc2V0dGltYW5hIGluaXppIGRpIGx1bmVkw6wKIyBjaSBzYXLDoCB1dGlsZSBkb3BvCkRhaWx5VmFsJERheU9mVGhlV2VlayA8LSBvcmRlcmVkKERhaWx5VmFsJERheU9mVGhlV2VlaywgbGV2ZWxzPWMoICJMdW4iICwgIk1hciIsICJNZXIiICwgIkdpbyIsICJWZW4iICwgICJTYWIiLCAiRG9tIiApKQpgYGAKClZlZGlhbW8gZGkgY29sb3JhcmUgaWwgZ3JhZmljbyBwcmVjZWRlbnRlIHVzYW5kbyB1biBjb2xvcmUgZGl2ZXJzbyBwZXIgb2duaSBnaW9ybm8gZGVsbGEgc2V0dGltYW5hLgoKYGBge3J9CnBsb3QoRGFpbHlWYWwkRGF0ZS5Mb2NhbCwgRGFpbHlWYWwkYG1heCBkYWlseSBQTSAxMGAsIHhsYWIgPSAiMjAxNiIsIHlsYWI9ICJQTSAxMCAodWcvbTMpIiwgY2V4ID0gLjgsIG1haW4gPSAiQ29uY2VudHJhemlvbmUgbWFzc2ltYSBnaW9ybmFsaWVyYSBkaSBQTTEwIiwgY29sID0gRGFpbHlWYWwkRGF5T2ZUaGVXZWVrKQphYmxpbmUoaCA9IDUwLCBjb2wgPSAicmVkIikKYGBgCgpWZWRpYW1vIGNoZSBub24gc2VtYnJhIGNoZSBpIHBpY2NoaSBzaWFubyByYWdnaXVudGkgbmVnbGkgc3Rlc3NpIGdpb3JuaS4gQ29tdW5xdWUgdW5hIGxlZ2VuZGEgYW5kcmViYmUgYWdnaXVudGEuIFZlZGlhbW8gY29uIGRlaSBib3hwbG90IGNvbWUgbGEgcXVhbnRpdMOgIG1lZGlhIGRpIHBvbHZlcmkgUE0xMCDDqCBkaXN0cmlidWl0YSByaXNwZXR0byBhaSBnaW9ybmkgZGVsbGEgc2V0dGltYW5hLgoKCmBgYHtyfQpib3hwbG90KGBtZWFuIGRhaWx5IFBNMTBgIH4gRGF5T2ZUaGVXZWVrLCBkYXRhID0gRGFpbHlWYWwsIHlsYWI9ICJQTSAxMCAodWcvbTMpIikKYGBgCgpBZ2dpdW5nZXJlIGFkIGVzZW1waW8gdW5hIGxpbmVhIGNoZSBpbmRpY2EgbGUgbWVkaWEgZGVsbGUgbWlzdXJhemlvbmksIGFpdXRhIGEgZmFyZSB1biBjb25mcm9udG8gdHJhIGkgZGF0aS4gCgpgYGB7cn0KYm94cGxvdCggYG1lYW4gZGFpbHkgUE0xMGAgfiBEYXlPZlRoZVdlZWssIGRhdGEgPSBEYWlseVZhbCwgeWxhYj0gIlBNIDEwICh1Zy9tMykiKQphYmxpbmUoaCA9IG1lYW4oRGFpbHlWYWwkYG1lYW4gZGFpbHkgUE0xMGApLCBjb2wgPSAicmVkIikKYGBgCgpWZWRpYW1vIGxhIGRhdGEgaW4gY3VpIMOoIHN0YXRvIGFzc3VudG8gaWwgdmFsb3JlIG1hc3NpbW86CgpgYGB7cn0KRGFpbHlWYWxbRGFpbHlWYWwkYG1lYW4gZGFpbHkgUE0xMGAgPiAyMCxdCmBgYAoKQ2hlIHNhcsOgIHN1Y2Nlc3NvIHF1ZWwgZ2lvcm5vPyBQb3RyZWJiZSBlc3NlcmUgdW4gZXJyb3JlIGRpIGxldHR1cmE/CgpTZSB2b2xlc3NpbW8gdmlzdWFsaXp6YXJlIGxhIGRpc3RyaWJ1emlvbmUgZGVpIGRhdGkgcmlzcGV0dG8gYWkgZ2lvcm5pLCBwb3NzaWFtbyB1c2FyZSBsYSBmdW56aW9uZSBgaGlzdCgpYC4gUHVydHJvcHBvIHRhbGUgZnVuemlvbmUgbm9uIHN1cHBvcnRhIGxhIG5vdGF6aW9uZSBgfmAsIHBlcmNpw7IgZG92cmVtbyBzcGVjaWZpY2FyZSB1biBncmFmaWNvIHBlciBnaW9ybm8gZGVsbGEgc2V0dGltYW5hLgoKYGBge3IsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gMTV9CnBhcihtZnJvdyA9IGMoNywxKSwgbWFyID0gYygyLDIsMSwxKSkKZm9yIChpIGluIGxldmVscyhEYWlseVZhbCREYXlPZlRoZVdlZWspICkgewogIGhpc3QoIERhaWx5VmFsW0RhaWx5VmFsJERheU9mVGhlV2VlayA9PSBpLCAibWVhbiBkYWlseSBQTTEwIl0gLCBmcmVxID0gRkFMU0UsIG1haW4gPSBpLCB5bGltID0gYygwLCAwLjIpICwgYnJlYWtzID0gc2VxKDAsMjYsMikpCn0KYGBgCgpEYWwgZ3JhZmljbyBwb3NzaWFtbyBjYXBpcmUgY29tZSBzaSBkaXN0cmlidWlzY29ubyBsZSBtaXN1cmF6aW9uaSByaXNwZXR0byBhaSBnaW9ybmkgZGVsbGEgc2V0dGltYW5hLiAKU2kgdXNpIGwnaGVscCBwZXIgY29tcHJlbmRlcmUgaSBwYXJhbWV0cmkgY2hlIHNvbm8gc3RhdGkgdXNhdGkuCgojIyBSZWdyZXNzaW9uZSAoRXNlcmNpemlvKQoKUG9zc2lhbW8gYW5hbGl6emFyZSBsYSByZWxhemlvbmUgdHJhIHRlbXBvIGUgaW5xdWluYW1lbnRvIHVzYW5kbyB1biBtb2RlbGxvIGxpbmVhcmU/IFByb3ZpYW1vIGUgY2VyY2hpYW1vIGRpIGNhcGlyZSBzZSBpbCBtb2RlbGxvIMOoIGFkZWd1YXRvLgoKCiMgKEV4dHJhKSBJbnF1aW5hbWVudG8gaW4gQ2FsaWZvcm5pYQoKRGVjaWRpYW1vIG9yYSBkaSBjb25jZW50cmFyZSBsYSBub3N0cmEgYXR0ZW56aW9uZSBzdWxsJ2lucXVpbmFtZW50byBpbiBDYWxpZm9ybmlhIGUgZG9wbyBhdmVyIGxldHRvIGlsIFtkYXRhc2V0XShodHRwOi8vYXFzZHIxLmVwYS5nb3YvYXFzd2ViL2Fxc3RtcC9haXJkYXRhL2RhaWx5XzgxMTAyXzIwMTYuemlwKSBjaGUgY29udGllbmUgaSB2YWxvcmkgKiptZWRpIGdpb3JuYWxpZXJpKiogZGkgUE0xMCwgc2FsdmlhbW8gdW4gc290dG9pbnNpZW1lIGRpIGRhdGkgY2hlIGNvbnRpZW5lIHNvbG8gZGF0aSByZWxhdGl2aSBhbGxhIENhbGlmb3JuaWEuCgpgYGB7cn0KUE0xMGRhdGEgPC0gcmVhZC5jc3YoIi4uL2RhdGEvZGFpbHlfODExMDJfMjAxNi5jc3YiKQpkaW0oUE0xMGRhdGEpCmBgYAoKVmVkaWFtbyBjaGUgaWwgZmlsZSDDqCBtb2x0byBncmFuZGUsIGNvbnRpZW5lIG1vbHRlIHJpZ2hlIGUgbW9sdGUgdmFyaWFiaWxpLiBSIGltcGllZ2EgZGl2ZXJzbyB0ZW1wbyBhIGxlZ2dlcmxvLgoKYGBge3J9CihQTTEwZGF0YUNBTCA8LSBQTTEwZGF0YVtQTTEwZGF0YSRTdGF0ZS5OYW1lID09ICJDYWxpZm9ybmlhIixdKQpgYGAKCkluIHF1ZXN0byBjYXNvIGlsIG5vbWUgZGVsbGEgdmFyaWFiaWxlIGNoZSBjaSBpbnRlcmVzc2Egw6ggKkFyaXRobWV0aWMuTWVhbiouCgpPcmEgdm9nbGlhbW8gdmlzdWFsaXp6YXJlIHN1IHVuYSBtYXBwYSBxdWFsaSBzb25vIGxvIGNpdHTDoCBjaGUgc3VwZXJhbm8gbGEgc29nbGlhIGRpIGlucXVpbmFtZW50byBjb25zZW50aXRhIGR1cmFudGUgbGUgb3NzZXJ2YXppb25pLiAgSW4gUiwgcXVlc3RhIG9wZXJhemlvbmUgw6ggbW9sdG8gc2VtcGxpY2UgdXNhbmRvIGkgcGFjY2hldHRpIGBtYXBzYCBvIGBSZ29vZ2xlTWFwc2AuCgpgYGB7ciwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0KI2luc3RhbGwucGFja2FnZXMoIm1hcHMiKQpsaWJyYXJ5KG1hcHMpCm1hcCgiY291bnR5IiwgImNhbGlmb3JuaWEiLCB4bGltPWMoLTEyNSwtMTE0KSwgeWxpbT1jKDMyLDQzKSkKcG9pbnRzKCBQTTEwZGF0YUNBTFtQTTEwZGF0YUNBTCRBcml0aG1ldGljLk1lYW4gPiA1MCxjKCJMb25naXR1ZGUiLCAiTGF0aXR1ZGUiKV0gLGNleCA9IC44LCBjb2wgPSAicmVkIikKYGBgCgpTZSB2b2dsaWFtbyB1c2FyZSB1bmEgbWFwcGEgZGkgR29vbGUgTWFwcyBwb3NzaWFtbyBmYXJsbyB1c2FuZG8gaWwgcGFjY2hldHRvIGRlZGljYXRvLgoKYGBge3IsIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gMTB9CiNpbnN0YWxsLnBhY2thZ2VzKCJSZ29vZ2xlTWFwcyIpCmxpYnJhcnkoUmdvb2dsZU1hcHMpCm1hcCA8LSBSZ29vZ2xlTWFwczo6R2V0TWFwKGNlbnRlcj0iQ2FsaWZvcm5pYSIsIHpvb20gPSA2KQptYXAxIDwtIHBsb3RtYXAoIGxhdCA9ICBQTTEwZGF0YUNBTFtQTTEwZGF0YUNBTCRBcml0aG1ldGljLk1lYW4gPiA1MCxjKCAiTGF0aXR1ZGUiKV0sIGxvbiA9ICBQTTEwZGF0YUNBTFtQTTEwZGF0YUNBTCRBcml0aG1ldGljLk1lYW4gPiA1MCxjKCJMb25naXR1ZGUiKV0gICxtYXAgPSBtYXApCmBgYAoKIyAoRXh0cmEpIElucXVpbmFtZW50byBhIExvcyBBbmdlbGVzCgpVc2lhbW8gbG8gc3Rlc3NvIGRhdGFzZXQgY29udGVuZW50ZSBpIGRhdGkgZ2lvcm5hbGllcmkgcmVsYXRpdmkgYWxsZSBQTTEwIG5lZ2xpIFN0YXRpIFVuaXRpIGUgY29uY2VudHJpYW1vY2kgc3VsbGEgc29sYSBjaXR0w6AgZGkgTG9zIEFuZ2VsZXMuCgpgYGB7cn0KUE0xMGRhdGFMQSA8LSBQTTEwZGF0YVtQTTEwZGF0YSRDaXR5Lk5hbWU9PSAiTG9zIEFuZ2VsZXMiLF0KZGltKFBNMTBkYXRhTEEpCmBgYAoKVmVkaWFtbyBjaGUgc29ubyBzdGF0ZSByYWNjb2x0ZSA5MCBvc3NlcnZhemlvbmkgcmVsYXRpdmUgYWxsYSBzb2xhIGNpdHTDoCBkaSBMQSwgY2VyY2hpYW1vIGRpIGNhcGlyZSBxdWFuZG8gZSBjb24gY2hlIGZyZXF1ZW56YSBzb25vIHN0YXRlIHJhY2NvbHRlLgoKYGBge3J9CnR5cGVvZihQTTEwZGF0YUxBKQpQTTEwZGF0YUxBJERhdGUuTG9jYWxbMToxMF0KYGBgCgpWZWRpYW1vIGNoZSBsZSBkYXRlIHNvbm8gc3RhdGUgc2FsdmF0ZSBjb21lIGxpc3RlLiBJbiByZWFsdMOgLCBjb21lIGdpw6AgdmlzdG8sICBSIHByZXZlZGUgaWwgZm9ybWF0byAqRGF0ZSogY2hlIHBvdHJlYmJlIGVzc2VyZSB1dGlsZSBlIHBpw7kgbWFuZWdnZXZvbGUgZGkgdW5hIGxpc3RhIHBlciBmYXJlICJvcGVyYXppb25pIGFyaXRtZXRpY2hlIi4gQ29udmVydGlhbW8gcXVpbmRpIGxhIGNvbG9ubmEgaW4gKkRhdGUqLgoKYGBge3J9ClBNMTBkYXRhTEEkRGF0ZS5Mb2NhbCA8LSBhcy5EYXRlKFBNMTBkYXRhTEEkRGF0ZS5Mb2NhbCkKdHlwZW9mKFBNMTBkYXRhTEEkRGF0ZS5Mb2NhbCkKYGBgCgpMYSB2YXJpYWJpbGUgb3JhIHJpc3VsdGEgZGkgdGlwbyAqRGF0ZS4qIFF1ZXN0byBjaSBwZXJtZXR0ZSwgYWQgZXNlbXBpbywgZGkgdmVkZXJlIHF1YW50aSBnaW9ybmkgcGFzc2FubyB0cmEgdW5hIHJpbGV2YXppb25lIGUgbCdhbHRyYS4KCmBgYHtyfQpkaWZmKFBNMTBkYXRhTEEkRGF0ZS5Mb2NhbCkKYGBgCgpTYWx0YSBhbGwnb2NjaGlvIGNoZSBsYSBmcmVxdWVuemEgZGVsbGUgcmVnaXN0cmF6aW9uaSDDqCBjaXJjYSBvZ25pIDYgZ2lvcm5pLCBtYSBjb21wYXJlIHVuIGRhdG8gaW5hdHRlc28uIEludmVzdGlnaGlhbW8gbWVnbGlvIGNvc2Egw6ggc3VjY2Vzc28uCgpgYGB7cn0KdW5pcXVlKFBNMTBkYXRhTEEkRGF0ZS5Mb2NhbCkKbGVuZ3RoKHVuaXF1ZShQTTEwZGF0YUxBJERhdGUuTG9jYWwpKQpgYGAKCkNhcGlhbW8gY2hlIHNlYmJlbmUgbGUgb3NzZXJ2YXppb25pIHNpYW5vIDkwLCBub24gdHV0dGUgc2kgcmlmZXJpc2Nvbm8gYSBnaW9ybmkgZGlmZmVyZW50aSwgcXVpbmRpIGJpc29nbmEgY2FwaXJlIGNvbWUgZ2VzdGlyZSBsZSBtaXN1cmF6aW9uaSByaXBldHV0ZSBkdXJhbnRlIGxvIHN0ZXNzbyBnaW9ybm8uIFZlZGlhbW8sIGFkIGVzZW1waW8sIGNvc2EgY2FyYXR0ZXJpenphIGxlIG1pc3VyYXppb25pIHJpcGV0dXRlIGRlbCBwcmltbyBnaW9ybm8gZGVsbCdhbm5vLgoKYGBge3J9ClBNMTBkYXRhTEFbUE0xMGRhdGFMQSREYXRlLkxvY2FsPT0gIjIwMTYtMDEtMDEiLF0KYGBgCgpQb3NzaWFtbyBvc3NlcnZhcmUgY2hlIGNpIHNvbm8gYWxtZW5vIGR1ZSBzaXRpIGRpdmVyc2kgZG92ZSB2ZW5nb25vIHJhY2NvbHRpIGkgZGF0aS4gUXVlc3RhIG9zc2VydmF6aW9uZSBzZWd1ZSBzaWEgbGEgY29tcGFyc2EgZGkgZHVlIGRpdmVyc2kgKlNpdGUuTnVtKiBwZXIgbGEgc3Rlc3NhIGRhdGEsIHNpYSBsZSBkaWZmZXJlbnplIG5laSB2YWxvcmkgZGkgX0xhdGl0dWRlXyBlIF9Mb25naXR1ZGVfLiBWZWRpYW1vIHNlIGVzaXN0b25vIHNvbG8gZHVlIHNpdGkgbyBwacO5LgoKYGBge3J9CnBhc3RlKHVuaXF1ZShQTTEwZGF0YUxBJFNpdGUuTnVtKSAsIHVuaXF1ZShQTTEwZGF0YUxBJExhdGl0dWRlKSwgdW5pcXVlKFBNMTBkYXRhTEEkTG9uZ2l0dWRlKSkKYGBgCgpBYmJpYW1vIGFwcHVyYXRvIGNoZSBlc2lzdG9ubyBkdWUgKGUgc29sbyBkdWUpIHNpdGkgaW5kaXZpZHVhdGkgZGEgZGl2ZXJzZSBjb29yZGluYXRlIGdlb2dyYWZpY2hlLgoKRXN0cmFwb2xpYW1vIG9yYSBhbGN1bmUgaW5mb3JtYXppb25pIHBlciBsZSB2YXJpYWJpbGkgbnVtZXJpY2hlIHVzYW5kbyBpbCBjb21hbmRvIGBzdW1tYXJ5KClgLgoKYGBge3J9CnN1bW1hcnkoUE0xMGRhdGFMQSkKYGBgCgpQb3NzaWFtbyBub3RhcmUgY2hlLCBhbmNoZSBpbiBxdWVzdG8gY2FzbywgYWxjdW5lIGRlbGxlIHZhcmlhYmlsaSBzb25vIHRyYXR0YXRlIGNvbWUgbnVtZXJpY2hlIGFuY2hlIHNlIGRvdnJlYmJlcm8gZXNzZXJlIGRpIHRpcG8gRmFjdG9yLiBQb3NzaWFtbyBvIGNvbnZlcnRpcmxlLCBvIHNlbXBsaWNlbWVudGUgdGVuZXJsbyBhIG1lbnRlIHF1YWxvcmEgZG92ZXNzaW1vIGxhdm9yYXJjaS4gUG9zc2lhbW8gYWx0cmltZW50aSByaW11b3ZlcmxlIGNvbWUgdmlzdG8gcHJpbWEuIAoKClBlciBwcmltYSBjb3NhLCBkZWZpbmlhbW8gdW4gY2FtcG8gZGkgaW50ZXJlc3NlLiBTZSB2b2dsaWFtbywgYWQgZXNlbXBpbywgdmVkZXJlIGwnYW5kYW1lbnRvIGRlbGxlIG1pc3VyYXppb25pIG1lZGllIGRpIFBNMTAgbmVpIGR1ZSBzaXRpLCBtb2x0ZSBkZWxsZSB2YXJpYWJpbGkgbm9uIGNpIGludGVyZXNzYW5vLiBQb3NzaWFtbyBpbnZlc3RpZ2FyZSBwacO5IG5lbCBkZXR0YWdsaW8gbGUgdmFyaWFiaWxpIGxlZ2F0ZSBhbGxhIG5vc3RyYSBpbmRhZ2luZSBlIG5vbiBjb25zaWRlcmFyZSBsZSBhbHRyZToKCgpgYGB7cn0KYm94cGxvdChBcml0aG1ldGljLk1lYW4gfiBTaXRlLk51bSwgZGF0YSA9IFBNMTBkYXRhTEEpCmBgYAoKUG9zc2lhbW8gbm90YXJlIGNoZSB1bm8gZGVpIGR1ZSBzaXRpIHByZXNlbnRhIGRlbGxlIG1pc3VyYXppb25pIGNoZSBpbiBnZW5lcmFsZSBzb25vIHBpw7kgYWx0ZS4gCgpgYGB7cn0KcGxvdChQTTEwZGF0YUxBJERhdGUuTG9jYWwgLCBQTTEwZGF0YUxBJEFyaXRobWV0aWMuTWVhbiwgY29sPSBQTTEwZGF0YUxBJFNpdGUuTnVtLCB4bGFiID0gIjIwMTYiLCB5bGFiID0gIm1lYW4gUE0xMCIpCmxlZ2VuZCggInRvcHJpZ2h0IiwgbGVnZW5kID0gYygiMTEwMyIsIjUwMDUiICksIGNvbD0gdW5pcXVlKFBNMTBkYXRhTEEkU2l0ZS5OdW0pLCBwY2ggPSBjKDEsMSkgKQpgYGAKCgpWZWRpYW1vIHNwYXppYWxtZW50ZSBkb3ZlIHNvbm8gcG9zaXppb25hdGkgaSBkdWUgcHVudGkgZGkgbW9uaXRvcmFnZ2lvLCBxdWVzdG8gcG90cmViYmUgc3BpZWdhcmUgbGUgZGlmZmVyZW56ZSBuZWxsZSBtaXN1cmF6aW9uaS4KCmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDEwfQptYXBMQSA8LSBSZ29vZ2xlTWFwczo6R2V0TWFwKGNlbnRlcj0iTG9zIEFuZ2VsZXMiLCB6b29tID0gMTApCm1hcExBMSA8LSBwbG90bWFwKCBsYXQgPSAgdW5pcXVlKFBNMTBkYXRhTEFbLGMoICJMYXRpdHVkZSIpXSksIGxvbiA9IHVuaXF1ZShQTTEwZGF0YUxBWyxjKCJMb25naXR1ZGUiKV0pICAsbWFwID0gbWFwTEEpCmBgYAoKRGFsbGEgbWFwcGEgc2VtYnJhIGNoZSB1bm8gZGVpIGR1ZSBzaXRpIChjZXJjaGkgbmVyaSkgc2lhIGluIGNlbnRybyBtZW50cmUgaWwgc2Vjb25kbyDDqCBwacO5IHZpY2lubyBhbGxhIHNwaWFnZ2lhLCBkb3ZlIHBvc3NpYW1vIGFzcGV0dGFyY2kgbWVubyB0cmFmZmljby4gCgpQZXIgYXZlcmUgdW5hIGNvbXByZW5zaW9uZSBtaWdsaW9yZSB2aXN1YWxpenppYW1vIHVuYSBtYXBwYSBkaWZmZXJlbnRlLCBjaGUgbW9zdHJhIHNpYSBsZSBzdHJhZGUgY2hlIGwnaW1tYWdpbmUgc2F0ZWxsaXRhcmUgZGVsbGEgem9uYS4KCmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDEwfQptYXBMQTEgPC0gcGxvdG1hcCggbGF0ID0gIHVuaXF1ZShQTTEwZGF0YUxBWyxjKCAiTGF0aXR1ZGUiKV0pLCBsb24gPSB1bmlxdWUoUE0xMGRhdGFMQVssYygiTG9uZ2l0dWRlIildKSAsIEFQSSA9ICJnb29nbGUiLCBtYXB0eXBlID0gImh5YnJpZCIsIHpvb20gPSAxMSkKVGV4dE9uU3RhdGljTWFwKG1hcExBMSxsYXQgPSAgdW5pcXVlKFBNMTBkYXRhTEFbLGMoICJMYXRpdHVkZSIpXSksIGxvbiA9IHVuaXF1ZShQTTEwZGF0YUxBWyxjKCJMb25naXR1ZGUiKV0pLGxhYmVscz0gdW5pcXVlKFBNMTBkYXRhTEFbLGMoICJTaXRlLk51bSIpXSksIGFkZD1UUlVFLCBjZXggPSAyLCBjb2wgPSAiZ3JlZW4iICwgcGNoID0gNikgCmBgYAoKVmVkaWFtbyBjaGUgaWwgc2Vjb25kbyBwdW50byBkaSBvc3NlcnZhemlvbmUsIHNlYmJlbmUgcmVnaXN0cmkgdmFsb3JpIHBpw7kgYmFzc2ksIHByb2JhYmlsbWVudGUgcGVyY2jDqSBwacO5IHZpY2lubyBhbGxhIHNwaWFnZ2lhLCDDqCBjb211bnF1ZSB2aWNpbm8gYWxsJ2Flcm9wb3J0by4gUXVlc3RvIHNpY3VyYW1lbnRlIGluZmx1ZW56YSBsYSBxdWFsaXTDoCBkZWxsJ2FyaWEgZSBwb3RyZWJiZSBzcGllZ2FyZSBwZXJjaMOpIHNlYmJlbmUgcGnDuSBiYXNzaSwgaSB2YWxvcmkgbm9uIHNpYW5vIGJhc3Npc3NpbWkuIE5vbiBjaSBzdHVwaXJlYmJlIHNlIGFsdHJpIHBhcmFtZXRyaSBtaXN1cmF0aSBmb3NzZXJvIGFkZGlyaXR0dXJhIHBlZ2dpb3JpIHJpc3BldHRvIGEgcXVlbGxpIHJlZ2lzdHJhdGkgaW4gY2VudHJvLiAKClNlbnphIG9wcG9ydHVuaSBzdHJ1bWVudGkgZGkgdmlzdWFsaXp6YXppb25lIGRlaSBkYXRpLCBub24gc2FyZW1tbyBwb3R1dGkgZ2l1bmdlcmUgYSBxdWVzdGUgY29uY2x1c2lvbmkuCg==